package indi.youxiaozhong.http.annotation;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;

// 支持的注解类型, 此处要填写全类名"indi.youxiaozhong.http.annotation.Interceptor",
@SupportedAnnotationTypes({"indi.youxiaozhong.http.annotation.RequestMapping"})
// JDK版本, 我用的是java7
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class RequestMappingProcessor extends AbstractProcessor {

    public static final String PREFIX = "My_";
    public static final String SUFFIX = "AutoGenerate";

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        // 准备在gradle的控制台打印信息
        Messager messager = processingEnv.getMessager();
        // 打印


        StringBuffer data = new StringBuffer();
        for (TypeElement te : annotations) {
            System.out.println(te.getClass().toString());
                //Interceptor interceptor  = te.getAnnotation(Interceptor.class);

//                if(interceptor!=null){
//                    //Element enclosingElement = e.getEnclosingElement();
//                    String enclosingQualifiedName = te.getQualifiedName().toString();// ((PackageElement)enclosingElement).getQualifiedName().toString();
//                    String name = interceptor.value();
//                    int order = interceptor.order();
//
//                    data.append("\ninterceptors.put(\""+name+"\",\""+order+":"+enclosingQualifiedName+"\");");
//                    continue;
//                }
            String rootPath = "";
            for (Element e : roundEnv.getElementsAnnotatedWith(te)) {
               // messager.printMessage(Diagnostic.Kind.NOTE, "Printing: " + e.toString());
                //messager.printMessage(Diagnostic.Kind.NOTE, "Printing: " + e.getSimpleName());
                //messager.printMessage(Diagnostic.Kind.NOTE, "Printing: " + e.getEnclosingElement().toString());



                // 获取注解
                RequestMapping annotation = e.getAnnotation(RequestMapping.class);

                if(annotation == null){
                    continue;
                }

                boolean isClass=false;
                //String className;

                // 获取元素名并将其首字母大写
                String name = e.getSimpleName().toString();
                //char c = Character.toUpperCase(name.charAt(0));
                //name = String.valueOf(c+name.substring(1));

                // 包裹注解元素的元素, 也就是其父元素, 比如注解了成员变量或者成员函数, 其上层就是该类
                Element enclosingElement = e.getEnclosingElement();
                // 获取父元素的全类名, 用来生成包名
                String enclosingQualifiedName;
                if(enclosingElement instanceof PackageElement){
                    isClass =true;
                    enclosingQualifiedName = ((PackageElement)enclosingElement).getQualifiedName().toString();
                }else{
                    isClass =false;
                    enclosingQualifiedName = ((TypeElement)enclosingElement).getQualifiedName().toString();


                }

                if (isClass){
                    //className = enclosingQualifiedName;
                    rootPath = annotation.value();
                    data.append("\n//"+rootPath +" --> "+enclosingQualifiedName);
                    continue;
                }

               // data.append("\n//"+rootPath+annotation.value() +" --> "+enclosingQualifiedName);
                String path = rootPath+annotation.value();
                String actionPath = enclosingQualifiedName+"/"+name;
                data.append("\nmapping.put(\""+path+"\",\""+actionPath+"\");");

            }


            try {
                // 生成的包名
                String genaratePackageName = "indi.youxiaozhong.faceid.devsetting.process"; //enclosingQualifiedName.substring(0, enclosingQualifiedName.lastIndexOf('.'));
                // 生成的类名
                String genarateClassName = PREFIX+"RequestMappingData"+SUFFIX; //PREFIX + enclosingElement.getSimpleName() + SUFFIX;

                // 创建Java文件
                JavaFileObject f = processingEnv.getFiler().createSourceFile(genarateClassName);
                // 在控制台输出文件路径
                messager.printMessage(Diagnostic.Kind.NOTE, "Printing: " + f.toUri());
                Writer w = f.openWriter();
                try {
                    PrintWriter pw = new PrintWriter(w);
                    pw.println("package " + genaratePackageName + ";");

                    pw.println("import java.util.Map;");
                    pw.println(" import indi.youxiaozhong.http.IRequestMappingData;");
                    pw.println("import java.util.HashMap;\n");


                    pw.println("public class " + genarateClassName + " implements IRequestMappingData { ");

                    pw.println("\nprivate Map<String,String>  mapping = new HashMap<>();");

                    pw.println("\nprivate Map<String,String>  interceptors = new HashMap<>();");

                    pw.println("\npublic My_RequestMappingDataAutoGenerate(){\n");
                    // pw.println("// "+rootPath+annotation.value()+" -> "+enclosingQualifiedName);

                    pw.println(data.toString());
                    pw.println("\n}");


                    pw.println("public Map<String, String> getMapping() {return mapping;}");

                    pw.println("public Map<String, String> getInterceptors() {return interceptors;}");


                    pw.println("}");
                    pw.flush();
                } finally {
                    w.close();
                }
            } catch (IOException x) {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,x.toString());
            }
        }

        return false;
    }

}
